<?php

namespace App\Http\Controllers\Admin\System;

use App\Enums\ResponseEnum;
use App\Http\Controllers\AdminController;
use App\Models\System\Menus;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Role;

class RoleController extends AdminController
{

    public function data(Request $request)
    {
        $model = Role::query()->select(['id', 'name', 'display_name', 'created_at', 'updated_at'])->where('guard_name', 'admin');
        if ($keyword = $request->get('keywords')) {
            $keyword = filterStr($keyword);
            $model->where(function ($query) use ($keyword) {
                $query->where('name', 'like', $keyword.'%')->orWhere('display_name', 'like', $keyword.'%');
            });
        }
        $list = $model->orderByDesc('id')->paginate($request->get('limit', 10));
        return $this->succeed([
            "total" => $list->total(),
            "rows" => $list->items()
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|max:30|unique:roles',
            'display_name'  => 'required'
        ], [
            'name.max' => '名称最大长度30个字符',
            'name.unique' => '名称已存在',
        ]);
        $data = $request->only(['name', 'display_name']);
        try {
            DB::transaction(function () use ($data) {
                $model = Role::query()->create([
                    'name' => $data['name'],
                    'guard_name' => 'admin',
                    'display_name' => $data['display_name'],
                ]);
                $this->createSyslog('添加角色', $model);
            });
            return $this->succeed();
        }catch (\Exception $e) {
            report($e);
        }
        return $this->error();
    }

    public function update(Request $request, $id)
    {
        $request->validate([
            'name' => 'required|max:30|unique:roles,name,'.$id.',id',
            'display_name' => 'required'
        ], [
            'name.max' => '名称最大长度30个字符',
            'name.unique' => '名称已存在',
        ]);
        $role = Role::query()->findOrFail($id);
        $data = $request->only(['name', 'display_name']);
        try {
            DB::transaction(function () use ($role, $data) {
                $role->update([
                    'name' => trim($data['name']),
                    'guard_name' => 'admin',
                    'display_name' => trim($data['display_name']),
                ]);
                $this->createSyslog('更新角色', $role);
            });
            return $this->succeed();
        }catch (\Exception $e) {
            report($e);
        }
        return $this->error();
    }

    public function destroy(Request $request)
    {
        $request->validate(['ids' => 'required|array|size:'.static::QUERY_LIMIT]);
        $ids = $request->get('ids');
        abort_if(in_array(1, $ids, true), ResponseEnum::ROLE_EXISTS_DELETE_ERROR);
        $list = Role::query()->select(['id'])->whereIn('id', $ids)->withCount('permissions')->limit(static::QUERY_LIMIT)->get();
        abort_if($list->isEmpty(), ResponseEnum::DELETE_NOT_EXIST_ERROR);
        try {
            DB::transaction(function () use ($list) {
                foreach ($list as $model) {
                    abort_if($model->permissions_count > 0, ResponseEnum::ROLE_EXISTS_PER_DELETE_ERROR);
                    $model->delete();
                    $this->createSyslog('删除角色', $model);
                }
            });
            return $this->succeed();
        }catch (\Exception $e) {
            report($e);
        }
        return $this->error();
    }

    public function permission($id)
    {
        $role = Role::query()->findOrFail($id);
        return $this->succeed([
            'list' => Menus::query()->select(['id', 'name', 'display_name', 'parent_id'])->get(),
            'checked' => $role->permissions()->pluck('name'),
        ]);
    }

    public function assignPermission($id, Request $request)
    {
        $role = Role::query()->findOrFail($id);
        $permissions = $request->get('permissions') ?? [];
        $role->syncPermissions($permissions);
        $this->createSyslog('更新角色权限', $permissions);
        return $this->succeed();
    }
}
